#ifndef ZONESMANAGER_H
#define ZONESMANAGER_H

#include <QObject>
#include <QStringlist>
#include <QVector>
#include <QDir>
#include <QFile>

#include "mainwindow.h"

#include "zonethread.h"

#include <optra/zoneinfo.h>
#include <optra/zoneinterface.h>



class Application;

class OptraZone;

struct ZoneProcess{
    Optra::ZoneInterface * zinterface;
    Optra::ZoneInfo *info;
    ZoneThread* thread;
};


struct ZoneInternalInfo{
    QStringList critdep;
    QStringList funtdep;
    QStringList futudep;
    QString path;
    QString displayName;
    QString unique;
    int dbid;
    QDir dir;
    QString desc;
};

class ZonesManager : public QObject
{
Q_OBJECT
public:
    typedef QMap<QString, ZoneInternalInfo> ZoneInfoMap;
    typedef QMap<QString, ZoneProcess> ZoneProcessMap;

    explicit ZonesManager(Application* main, QObject *parent = 0);
    ~ZonesManager();

    bool installZone(ZoneInternalInfo& zi);
    bool installZone(QFile* file);

    bool loadZones();
    void unloadZones();
    Optra::ZoneInterface* zoneInterface(const QString& name);
    ZoneProcessMap zoneProcess() { return zoneProcess_; };

    OptraZone* optra();

    bool zoneInstaled(const ZoneInternalInfo& info, int* id = 0);

    bool zoneInfoId(int id, ZoneInternalInfo& info);
    bool zoneInfoUnique(const QString& unique, ZoneInternalInfo* info = 0);
    bool zoneDrop(int id);
    int zoneDependency(const QString& name);

signals:
    void zonesLoaded();
    void zonesXmlChecked();
    void zonesCreated();
    void zonesConfigured();
    void zonesConected();
    void zonesLaunched();

    void launchInitialize();
    void launchLaunch();

public slots:
private slots:
    void create();
    void configure();
   // void initialize();
    void dependency();
    void connect();
    void launch();

private:

    bool parseFolderElement(const QDomElement &element, ZoneInternalInfo& zi);
    bool parseDependencyElement(const QDomElement &element, ZoneInternalInfo& zi);
    void setupZone(Optra::ZoneInterface* zone, const QDir& working);
    bool processZone(QFile* xmlFile, ZoneInternalInfo& zi);
    bool createZone(const QString& entryFile);
    bool setDBDependency(const QStringList& sl, int sid, const QString& depname);
    bool recordZoneToInfo(QSqlRecord record, ZoneInternalInfo& info);

    void updateZonesDependency(const QString& unique, int id);

    QStringList errors;
    //QStringList warnings;
    //QStringList errors;

    QVector <Optra::ZoneInterface*> zones_;
    ZoneProcessMap zoneProcess_;
    OptraZone* optrazone_;

    ZoneInfoMap zoneinfo_;
    Application* main_;

    QList<QLibrary*> zones_libs;
    QSettings::Format dbFormat;
};

#endif // ZONESMANAGER_H
